package com.woniu.guoguo.controller;

import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.woniu.guoguo.bean.AlipayBean;
import com.woniu.guoguo.common.Result;
import com.woniu.guoguo.config.PropertiesConfig;
import com.woniu.guoguo.model.*;
import com.woniu.guoguo.service.*;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;


import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @author： Micsal
 * @create-time： 2020.11.03 16:29
 * @version： 1.0
 * @description： desc
 */
@RestController
@Slf4j
public class AheadController {
    @Autowired
    private IRestaurantService restaurantService;
    @Autowired
    private IRestaurantImgService restaurantImgService;
    @Autowired
    private IMenuService menuService;
    @Autowired
    private IMenuImgService menuImgService;
    @Autowired
    private IMenuCommentsService menuCommentsService;
    @Autowired
    private IUserService userService;
    @Autowired
    private IMenuCommentsImgService menuCommentsImgService;
    @Autowired
    private IOrderService orderService;
    @Autowired
    private IPayService payService;
    @Autowired
    private IMenuActiveService menuActiveService;

    /**
     * 获取餐厅的所有信息(菜单信息，菜单图片，各餐厅信息，各餐厅的图片)
     *
     * @param menuId
     * @return
     */
    @GetMapping("/getMessageByRestaurantId")
    public Result f1(int menuId, double myLnt, double myLat, HttpSession session) {
        log.info("请求菜单信息{}，{}，{}", menuId, myLnt, myLat);
        Object o=session.getAttribute("menuId");
        if(null==o){
            return Result.fail("访问失效");
        }
        menuId=(int)o;
        if (menuId <= 0) {
            return Result.fail("请求失败，非法请求ID参数");
        }
        Menu menu = menuService.getById(menuId);
        if (null == menu) {
            return Result.fail("请求失败，菜单不存在");
        }
        if (menu.getStatus() == 0) {
            return Result.fail("请求失败，菜单已下架");
        }
        //获取菜单图片
        List<String> menuImgs = menuImgService.findImagesByMenuId(menuId);
        //获取店铺列表
        List<Restaurant> restaurants1 = restaurantService.getCloseRestaurants(myLnt, myLat);
        List<Restaurant> restaurants = new ArrayList<>();
        for (Restaurant r : restaurants1) {  //去除未开业的店
            if (r.getStatus() == 01) {
                restaurants.add(r);
            }
        }
        //获取店铺的图片
        @Data
        @AllArgsConstructor
        class restImags {
            private int id;
            private List<String> imgs;
        }
        List<restImags> ms = new ArrayList<>();
        for (Restaurant r1 : restaurants) {
            if (r1.getStatus() == 1) {
                List<String> mgs = restaurantImgService.findImagesByRestId(r1.getRestaurantId());
                ms.add(new restImags(r1.getRestaurantId(), mgs));
            }
        }
        Map<String, Object> data = new HashMap<>();
        data.put("restData", restaurants);
        data.put("restImgs", ms);
        data.put("menuDatas", menu);
        data.put("menuImgs", menuImgs);
        return Result.success(data);
    }

    /**
     * 分页查询评论
     *
     * @param menuId
     * @return
     */
    @GetMapping("/getCommentsByPage")
    public Result f2(int currentPage, int pageSize, int menuId,HttpSession session) {
        log.info("评论分页查询{},{},{}", currentPage, pageSize, menuId);
        Object o=session.getAttribute("menuId");
        if(null==o){
            return Result.fail("登录失效");
        }
        menuId=(int)o;
        //评论的分页
        Page<MenuComments> page = new Page<>();
        page.setCurrent(currentPage);
        page.setSize(pageSize);
        IPage<MenuComments> ipage = menuCommentsService.findCommentsByMenuId(page, menuId);
        //获取评论的图片,用户名
        @Data
        @AllArgsConstructor
        class menuCommImgs {
            private int id;
            private String userName;
            private List<String> imgs;
        }
        List<menuCommImgs> ms = new ArrayList<>();
        for (MenuComments mc : ipage.getRecords()) {
            String un = userService.getById(mc.getUserId()).getUsername();
            List<String> mgs = menuCommentsImgService.findCommentsImgByCommentId(mc.getId());
            ms.add(new menuCommImgs(mc.getId(), un, mgs));
        }
        Map<String, Object> data = new HashMap<>();
        data.put("ipage", ipage);
        data.put("menuCommImgs", ms);
        return Result.success(data);
    }

    /**
     * 获取menuId 和 显示加评论flag
     *
     * @param menuId
     * @param session
     * @return
     */
    @GetMapping("/getMenuIdAndCommentsStatus")
    public Result f3(int menuId, HttpSession session) {
        log.info("获取MenuId和评论与否");
        int userId = 0;
//        userId=(int)session.getAttribute("userId");
        menuId=(int)session.getAttribute("menuId");
        boolean bo = false;
        if (session.getAttribute("userid") != null) {
            userId = (Integer) session.getAttribute("userid");
            Order order = orderService.findOrderByUserIdAndMenuId(menuId, userId);
            log.info("获取到订单状态{}", order);
            if (null != order && order.getState() == 1) {
                log.info("订单存入session,{}", order);
                bo = true;
                session.setAttribute("orderState2", order);
            }
        }
        Map<String, Object> data = new HashMap<>();
        data.put("menuId", menuId);
        data.put("addCommentsModel", bo);
//        data.put("addCommentsModel", true);
        return Result.success(data);
    }

    /**
     * 添加评论
     *
     * @return
     */
    @PostMapping(value = "/addComments", produces = "application/json;charset=utf-8")
    public Result f4(MultipartFile[] files, double score1, double score2, double score3, String comments, HttpSession session) {
        log.info("添加评论,{},{}", files.length, comments);
        if(session.getAttribute("userid")==null){
            return Result.fail("请登录后操作");
        }
        int userId = (int) session.getAttribute("userid");
        int menuId = (int) session.getAttribute("menuId");

        Order order = (Order) session.getAttribute("orderState2");

        List<MenuCommentsImg> ms = new ArrayList<>();
//        Order order = orderService.findOrderByUserIdAndMenuId(menuId, userId);
        log.info("获取到session中的订单{}", order);
        double score = (score1 + score2 + score3) / 3;
        int orderId = order.getOrderId();
        if (files.length != 0) {
            for (MultipartFile f : files) {
                if (null != f) {
                    String fileName = UUID.randomUUID().toString() + f.getOriginalFilename();
                    String path = "/root/mine/static/comments_img/" + fileName;
                    try {
                        f.transferTo(new File(path));
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
//                    File file = new File(path);
                    String url = "http://101.132.138.195:8000/comments_img/" + fileName;
                    MenuCommentsImg m1 = new MenuCommentsImg(0, menuId, url);
                    ms.add(m1);
                }
            }
        }
        MenuComments menuComments = new MenuComments(0, menuId, userId, comments, score, new Date());
        menuCommentsService.insertAMenuComment(menuComments);
        for (MenuCommentsImg m3 : ms) {
            m3.setMenuCommentsId(menuComments.getId());
        }
        orderService.updateStateTo3ById(order.getOrderId());
        menuCommentsImgService.saveBatch(ms);
        return Result.success();
    }


    /**
     * 支付请求处理
     *
     * @return
     * @throws AlipayApiException
     */
    @PostMapping(value = "/alipay")
    public Result alipay(@RequestBody Restaurant restaurant, HttpSession session) throws AlipayApiException {
        log.info("支付请求处理:{}", restaurant);
        if(session.getAttribute("userid")==null){
            return Result.fail("请登录后操作");
        }
        int menuId = (int) session.getAttribute("menuId");
        int userId = (int) session.getAttribute("userid");

        session.setAttribute("shopShopping", restaurant);
//        int usrId = 1;
//        int menuId = 1;
        User user = userService.getById(userId);
        Menu menu = menuService.getById(menuId);
        String out_trade_no = userId + "_" + restaurant.getRestaurantId() + "_" + menuId + "_" + System.currentTimeMillis();
        String subject = menu.getType();
        double price = 0;
        price = user.getVip() == 1 ? menu.getPrice() * menu.getDiscounts() * menu.getVipPrice() : menu.getPrice() * menu.getDiscounts();
        price = (double) Math.round(price * 100) / 100;
        String total_amount = price + "";
        String body = menu.getMenuName();
        String s = payService.aliPay(new AlipayBean()
                .setBody(body)                      //商品描述
                .setOut_trade_no(out_trade_no)      //商户订单号
                .setTotal_amount(new StringBuffer().append(total_amount))   //付款金额
                .setSubject(subject));            //订单名称
        log.info("请求后返回的字符串:{}", s);        //是一个前端页面
        return Result.success(s);
    }

    /**
     * 支付宝服务器异步通知页面
     *
     * @param request
     * @return
     * @throws AlipayApiException
     */
    Lock lock=new ReentrantLock();
    @RequestMapping("/AlipayNotifyUrl")
    public String alipayNotify(HttpServletRequest request, String out_trade_no, String trade_no, String trade_status, HttpSession session) throws AlipayApiException {
        log.info("进入异步回调");
        Map<String, String> params = getParamsMap(request);
        log.info("支付异步回调，请求头内容: {}", JSONObject.toJSON(params));
        // 验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(params, PropertiesConfig.getKey("alipay_public_key"), PropertiesConfig.getKey("charset"), PropertiesConfig.getKey("sign_type"));
        log.info("支付异步回调，验证签名 : {}", signVerified);
        if (signVerified) {
            trade_status = request.getParameter("trade_status");
            log.info("签名验证成功，获取支付状态：{}", trade_status);
            if (trade_status.equals("TRADE_SUCCESS")) {
                String otn = params.get("out_trade_no");
                Order o1 = orderService.findOrderByOutTradeNo(otn);
                if (o1 == null) {   //没有该订单才添加订单
                    String info[] = otn.split("_");   //解析出各类id
                    int userId,restId,menuId;
                    String s="";
                    if(info[0].equals("active")){
                        s=info[0];
                        userId = Integer.parseInt(info[1]);
                        restId = Integer.parseInt(info[2]);
                        menuId = Integer.parseInt(info[3]);
                    }else{
                        userId = Integer.parseInt(info[0]);
                        restId = Integer.parseInt(info[1]);
                        menuId = Integer.parseInt(info[2]);
                    }
                    if(s.equals("active")){
                        lock.lock();
                        try{
                            log.info("异步回调，秒杀活动，数量减1，同步锁");
                            menuActiveService.decreaseOneActiveNumberByMenuId(menuId);
                        }catch (Exception e) {
                            e.printStackTrace();
                            log.info("异步回调，同步锁，捕获异常{}",e.getMessage());
//                            return e.getMessage();
                        }finally {
                            lock.unlock();
                            log.info("异步回调，解锁");
                        }
                    }
                    Restaurant restaurant = restaurantService.getById(restId);
                    log.info("异步回调获取的订单号信息：{}", otn);
                    menuService.addASaleByMenuId(menuId);   //菜单销量+1
                    String moneyst = params.get("invoice_amount");    //获取金额
                    double money = Double.parseDouble(moneyst);
                    restaurantService.addMoneyByRestaurantId(restaurant.getRestaurantId(), money);   //分店+钱
                    String s1 = params.get("body");       //描述

                    String checkCode = otn.substring(11); //校验码
                    Order order = new Order(0, userId, s1, moneyst, 0, restaurant.getRestaurantId(), checkCode, menuId, 1, otn);
                    orderService.addAOrderBuySys(order);
                }
            }
            return ("success");
        } else {
            log.info("签名验证失败");
            return ("fail");
        }

    }

    /**
     * 支付宝服务器同步通知页面
     *
     * @return
     * @throws AlipayApiException
     */
    @RequestMapping("/AplipayReturnUrl")
    public String alipayReturn(HttpServletRequest request, HttpServletResponse response) throws AlipayApiException, IOException {
        Map<String, String> params = getParamsMap(request);
        log.info("进入同步回调: {}", JSONObject.toJSON(params));
        // 验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(params, PropertiesConfig.getKey("alipay_public_key"), PropertiesConfig.getKey("charset"), PropertiesConfig.getKey("sign_type"));
        log.info("同步回调，验证签名: {}", signVerified);
        if (signVerified) {
//            if(request.getSession().getAttribute("menuActive")!=null){
//                response.sendRedirect("/html/MenuManagerActive.html");    //重定向
//            }else
//            {
                response.sendRedirect("/html/MenuManager.html");    //重定向
//            }
        } else {
            log.info("验证失败,不去更新状态");
            return ("验证失败");
        }
        return "";
    }

    /**
     * 获取request中的参数
     *
     * @param request
     * @return
     */
    private Map<String, String> getParamsMap(HttpServletRequest request) {
        Map<String, String> params = new HashMap<>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
            params.put(name, valueStr);
        }
        return params;
    }


    @GetMapping("/getSearchResult")
    public Result search(String message, String type, HttpSession session) {
        log.info("搜索的参数为：{}，{}", message, type);

        session.setAttribute("searchWord", message);

        return Result.success();
    }




    /**
     * 获取秒杀的信息 -- 初始渲染页面
     * @return
     */
    Lock lock1=new ReentrantLock();
    @GetMapping("/getAllActiveMenuMessage")
    public Result f5(){
        log.info("------ 拉取秒杀信息");
        List<MenuActive> menuActive=null;
        lock1.lock();
        try{
            menuActive=menuActiveService.list();
            log.info("加锁，锁对象:{}",lock);
        }catch (Exception e){
            e.printStackTrace();
            log.info("同步锁异常:{}",e.getMessage());
        }finally{
            lock1.unlock();
            log.info("解锁");
        }
        List<Menu> menu1=new ArrayList<>();     //菜单集合
        List<MenuImg> menuImg1=new ArrayList<>();   //菜单图片集合
        List<MenuActive> menuActive1=new ArrayList<>(); //未开始的活动集合
        List<MenuActive> menuActive2=new ArrayList<>(); //正在进行的活动集合
        for(MenuActive m1:menuActive){
            if(m1.getEndTime().before(new Date())||m1.getActiveNumber()<=0){ //活动结束
                m1.setState(2);
                menuActiveService.updateById(m1);
            }else if(m1.getBeginTime().after(new Date())){  //活动未开始
                m1.setState(0);
                menuActiveService.updateById(m1);
                menuActive1.add(m1);
            }else{                          //正在进行的活动
                m1.setState(1);
                menuActiveService.updateById(m1);
                menuActive2.add(m1);
                int x=m1.getMenuId();
                menu1.add(menuService.getById(x));  //获取menu
                List<String> ls1=menuImgService.findImagesByMenuId(x);
                String img1= ls1.size()==0?"../img/假装有图.jpg":ls1.get(0);   //获取1张图片 没有则是默认图片
                menuImg1.add(new MenuImg(0,x,img1));
            }
        }
        if(menuActive2.size()<4){   //活动没有4个话添加未开始的活动
            int x1=menuActive2.size();
            int x2=menuActive1.size();
            for(int i=0;(i<(4-x1))&&(i<x2);i++){
                MenuActive m1=menuActive1.get(i);
                int x=m1.getMenuId();
                menuActive2.add(m1);
                menu1.add(menuService.getById(x));  //获取menu
                List<String> ls1=menuImgService.findImagesByMenuId(x);
                String img1= ls1.size()==0?"../img/假装有图.jpg":ls1.get(0);   //获取1张图片 没有则是默认图片
                menuImg1.add(new MenuImg(0,x,img1));
            }
        }
        log.info("进行中活动个数:{},未开始活动个数:{}",menuActive2.size(),menuActive1.size());
        if(menuActive2.size()==0){
            return Result.fail("暂时没有秒杀活动");
        }
        Map<String, Object> data=new HashMap<>();
        data.put("menu1",menu1);
        data.put("menuActive1",menuActive2);
        data.put("menuImage1",menuImg1);
        return Result.success(data);
    }




    /**
     * 秒杀抢购跳转
     * @return
     */
    @GetMapping("/getSecondsKillActivity")
    public Result f6(HttpSession session, int id){
        MenuActive menuActive=menuActiveService.getById(id);
        log.info("------ 秒杀处理:{}",menuActive);
        if(session.getAttribute("userid")==null) {
            return Result.fail("请登录后再操作");
        }
        session.setAttribute("menuActive",menuActive);
        session.setAttribute("menuId",menuActive.getMenuId());
        return Result.success();
    }

    /**
     * 跳转后获取价格和数量
     * @return
     */
    @GetMapping("/getMenuActiveMessage")
    public Result f7(HttpSession session){
        log.info("------ 获取秒杀信息:");
        if(session.getAttribute("userid")==null) {
            return Result.fail("请登录后再操作");
        }
        if(session.getAttribute("menuActive")==null){
            return Result.fail("信息失效，请重新抢购");
        }
        MenuActive menuActive=(MenuActive) session.getAttribute("menuActive");
        Map<String, Object> data=new HashMap<>();
        data.put("menuActivePrice",menuActive.getActivePrice());
        data.put("menuActiveNumber",menuActive.getActiveNumber());
        return Result.success(data);
    }

    //查询用户余额
    @GetMapping("querybalance")
    public Result querybalance(HttpSession session){
        int userId = (int) session.getAttribute("userid");
        User findbyuserid = userService.findbyuserid(userId);
        return Result.success(findbyuserid);
    }
    //添加订单
    @GetMapping("querypay")
    public Result addorder(int restaurantId,HttpSession session){
        boolean bool =false;
        int userId = (int) session.getAttribute("userid");
        int menuId = (int) session.getAttribute("menuId");
        User user = userService.getById(userId);
        Menu menu = menuService.getById(menuId);
        if (user.getBalance()>=menu.getPrice()){
            Order order = new Order();
            order.setUserId(userId);
            order.setMenuId(menuId);
            order.setDescription(menu.getMenuName());
            int price = (int) (user.getVip() == 1 ? menu.getPrice() * menu.getDiscounts() * menu.getVipPrice() : menu.getPrice() * menu.getDiscounts());
            order.setPrice(price+"");
            order.setShopId(restaurantId);
            int  maxNum = 36;
            int i;
            int count = 0;
            char[] str = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K',
                    'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W',
                    'X', 'Y', 'Z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
            StringBuffer invitationCode1  = new StringBuffer("");
            Random r1 = new Random();
            while(count < 10){
                i = Math.abs(r1.nextInt(maxNum));
                if (i >= 0 && i < str.length) {
                    invitationCode1.append(str[i]);
                    count ++;
                }
            }
            String invitationCode = invitationCode1.toString();
            order.setCheckCode(invitationCode);
            order.setOutTradeNo("19_5_8_2"+invitationCode);
            //新增订单表
            userService.addorder(order);
            //修改用户余额
            userService.changebalance(price,userId);
            //增加商家余额
            userService.changeshop(price,restaurantId);
            bool=true;
        }

        return Result.success(bool);
    }



}
